package cn.com.cfae.iras.doc.analyze.parse.extractor;

import cn.com.cfae.iras.doc.analyze.keys.ExtractMethod;
import cn.com.cfae.iras.doc.analyze.parse.kv.KVText;
import cn.com.cfae.iras.doc.analyze.parse.model.*;
import cn.com.cfae.iras.doc.analyze.parse.tokenizer.FXJGTokenizer;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 抽取发行有关机构
 */
public class M12Extractor extends MTableExtractor {
    private static final Logger logger = LoggerFactory.getLogger(M12Extractor.class);

    private FXJGTokenizer fxjgTokenizer = FXJGTokenizer.getInstance();

    @Override
    public void extract() {
        try {
            extractM12();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    private void extractM12() {
        long t1 = System.currentTimeMillis();
        logger.info("开始抽取{}章业务模型数据......", getChapterModel().getChapterId());
        try {
            extractM12Fxjg3();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        long t2 = System.currentTimeMillis();
        logger.info("抽取{}章业务模型数据完成，耗时：{}毫秒。", getChapterModel().getChapterId(), (t2 - t1));
    }


    private static List<String> filters = new ArrayList<>();

    static {
        filters.add("联席主承销商");
        filters.add("承销团");
    }

    private void extractM12Fxjg3() {
        long t1 = System.currentTimeMillis();
        logger.info("开始抽取{}章发行机构业务模型数据......", getChapterModel().getChapterId());
        List<PageModel> pageModelList = getPageModelList();
        ExtractBizModel extractBizModel = getChapterModel().getModel(FXJGModel.MODEL_NAME);
        ExtractMethod[] extractMethods = extractBizModel.getExtractMethods();
        Map<String, ExtractBizModel> extractBizModelMap = getChapterModel().getExtractBizModelMap();
        fxjgTokenizer.loadCoreSynonyms2(extractBizModelMap);
        fxjgTokenizer.loadCoreSynonyms(extractBizModel);
        PageModel pageModel = null;
        ExtractItem currentExtractItem = null;
        ExtractItem nextExtractItem = null;
        ExtractBizModel targetExtractBizModel = null;
        for (int i = 0; i < pageModelList.size(); i++) {
            pageModel = pageModelList.get(i);
            logger.info("抽取{}章发行机构业务模型数据，当前页码：{}，分析文本：{}。", getChapterModel().getChapterId(), pageModel.getPageNumber(), pageModel.getJsonTextData());
            if (pageModel != null) {
                List<String> extractTableDataList = null;
                ExtractMethod extractMethod = extractMethods[0];
                ExtractItem extractItem = null;
                switch (extractMethod) {
                    case TEXT:
                        break;
                    case KV:
                        try {
                            extractTableDataList = extractPdfByTable(new String[]{getDocumentModel().getPdfFilePath(), "-l", "-p", String.valueOf(pageModel.getPageNumber()), "-a", pageModel.getDefaultPageArea().getLayout(), "-f", "JSON"});
                        } catch (Exception e) {
                            logger.error("抽取PDF文件内容发生异常，异常信息如下：");
                            logger.error(e.getMessage(), e);
                            continue;
                        }
                        if (CollectionUtils.isEmpty(extractTableDataList)) {
                            logger.info("抽取{}章发行机构业务模型数据，数据格式为文本形式，适用默认文本值进行分析，分析文本：{}。", getChapterModel().getChapterId(), pageModel.getJsonTextData());
                            JsonArray dataArray = getPageDataArray(pageModel);
                            for (int j = 0; j < dataArray.size(); j++) {
                                JsonArray lineArray = dataArray.get(j).getAsJsonArray();
                                String combineLine = combineTextJsonArray(lineArray);
                                if (isEmpty(combineLine)) {
                                    continue;
                                }
                                logger.info("抽取{}章发行机构业务模型数据，分析文本：{}。", getChapterModel().getChapterId(), combineLine);
                                nextExtractItem = fxjgTokenizer.splitWords(extractBizModel, replaceSpaces(combineLine));
                                if (nextExtractItem == null && currentExtractItem == null) {
                                    logger.error("抽取{}章发行机构业务模型数据，未能分析到发行机构信息，分析文本：{}。", getChapterModel().getChapterId(), combineLine);
                                    continue;
                                } else if (nextExtractItem != null) {
                                    currentExtractItem = nextExtractItem;
                                }
//                                currentExtractItem = nextExtractItem;
                                targetExtractBizModel = getChapterModel().getExtractBizModelMap().get(currentExtractItem.getItemName());
                                if (!filters.isEmpty()) {
                                    for (String var1 : filters) {
                                        if (combineLine.contains(var1)) {
                                            targetExtractBizModel = null;
                                            currentExtractItem = null;
                                            break;
                                        }
                                    }
                                }
                                if (targetExtractBizModel == null) {
                                    logger.error("抽取{}章发行机构业务模型数据，未能分析到或者跳过指定发行机构信息，分析文本：{}。", getChapterModel().getChapterId(), combineLine);
                                    continue;
                                }
                                logger.error("抽取{}章发行机构业务模型数据，当前业务模型：{}，分析文本：{}。", getChapterModel().getChapterId(), targetExtractBizModel.getModelName(), combineLine);
                                combineLine = combineTextJsonArray(dataArray.get(j).getAsJsonArray());
                                extractItem = fxjgTokenizer.splitWords(targetExtractBizModel, replaceSpaces(combineLine));
                                if (extractItem != null) {
                                    if (extractItem.getValue() != null) {
                                        continue;
                                    }
                                    combineLine = replaceSpaces(combineLine);
                                    if (isFXJG_SPLIT_Format(combineLine)) {
                                        if (isFilter(combineLine)) {
                                            continue;
                                        }
                                        String splitChar = findFXJG_Format_Split_Char(combineLine);
                                        String[] splits = combineLine.split(splitChar);
                                        if (splits.length == 2) {
                                            try {
                                                String key = splits[0];
                                                String value = splits[1];
                                                KVText kText = new KVText();
                                                kText.setText(key);
                                                kText.add(createKVTextLayout(pageModel, lineArray));
                                                KVText vText = new KVText();
                                                vText.setText(value);
                                                vText.add(createKVTextLayout(pageModel, lineArray));
                                                vText.getTextLayout().setText(vText.getText());
                                                extractItem.setKey(kText);
                                                extractItem.setValue(vText);
                                                kText.setPageNumber(pageModel.getPageNumber());
                                                vText.setPageNumber(pageModel.getPageNumber());
                                            } catch (Exception e) {
                                                logger.error(e.getMessage(), e);
                                            }
                                        } else if (splits.length == 3) {
                                            try {
                                                String key = splits[1];
                                                String value = splits[2];
                                                KVText kText = new KVText();
                                                kText.setText(key);
                                                kText.add(createKVTextLayout(pageModel, lineArray));
                                                KVText vText = new KVText();
                                                vText.setText(value);
                                                vText.add(createKVTextLayout(pageModel, lineArray));
                                                vText.getTextLayout().setText(vText.getText());
                                                extractItem.setKey(kText);
                                                extractItem.setValue(vText);
                                                kText.setPageNumber(pageModel.getPageNumber());
                                                vText.setPageNumber(pageModel.getPageNumber());
                                            } catch (Exception e) {
                                                logger.error(e.getMessage(), e);
                                            }
                                        } else {
                                            if (getPageModelBottomPageNum(dataArray.get(j + 1).getAsJsonArray())>0) {
                                                continue;
                                            }
                                            combineLine = combineTextJsonArray(dataArray.get(j + 1).getAsJsonArray());
                                            combineLine = replaceSpaces(combineLine);
                                            if (isFXJG_SPLIT_Format(combineLine)) {
                                                continue;
                                            }
                                            if (isFilter(combineLine)) {
                                                continue;
                                            }
                                            try {
                                                String key = combineLine;
                                                String value = key;
                                                KVText kText = new KVText();
                                                kText.setText(key);
                                                kText.add(createKVTextLayout(pageModel, lineArray));
                                                KVText vText = new KVText();
                                                vText.setText(value);
                                                vText.add(createKVTextLayout(pageModel, lineArray));
                                                vText.getTextLayout().setText(vText.getText());
                                                extractItem.setKey(kText);
                                                extractItem.setValue(vText);
                                                kText.setPageNumber(pageModel.getPageNumber());
                                                vText.setPageNumber(pageModel.getPageNumber());
                                            } catch (Exception e) {
                                                logger.error(e.getMessage(), e);
                                            }
                                        }
                                    } else {
                                        if (getPageModelBottomPageNum(dataArray.get(j + 1).getAsJsonArray())>0) {
                                            continue;
                                        }
                                        combineLine = combineTextJsonArray(dataArray.get(j + 1).getAsJsonArray());
                                        combineLine = replaceSpaces(combineLine);
                                        if (isFXJG_SPLIT_Format(combineLine)) {
                                            continue;
                                        }
                                        if (isFilter(combineLine)) {
                                            continue;
                                        }
                                        try {
                                            String key = combineLine;
                                            String value = key;
                                            KVText kText = new KVText();
                                            kText.setText(key);
                                            kText.add(createKVTextLayout(pageModel, lineArray));
                                            KVText vText = new KVText();
                                            vText.setText(value);
                                            vText.add(createKVTextLayout(pageModel, lineArray));
                                            vText.getTextLayout().setText(vText.getText());
                                            extractItem.setKey(kText);
                                            extractItem.setValue(vText);
                                            kText.setPageNumber(pageModel.getPageNumber());
                                            vText.setPageNumber(pageModel.getPageNumber());
                                        } catch (Exception e) {
                                            logger.error(e.getMessage(), e);
                                        }
                                    }
                                }
                            }
                        } else {
                            logger.info("抽取{}章发行机构业务模型数据,该页码含误导信息，实际数据格式为文本形式，适用默认文本值进行分析，分析文本：{}。", getChapterModel().getChapterId(), pageModel.getJsonTextData());
                            JsonElement tableData = str2Json(extractTableDataList.get(0));
                            JsonObject jsonObject = tableData.getAsJsonArray().get(0).getAsJsonObject();
                            JsonArray dataArray = jsonObject.get("data").getAsJsonArray();
                            if (dataArray.size() <= 3) {
                                logger.info("抽取{}章发行机构业务模型数据,执行到该处应该为发行机构首页，该页码含误导信息，实际数据格式有可能为文本形式，适用默认文本值进行分析，分析文本：{}。", getChapterModel().getChapterId(), pageModel.getJsonTextData());
                                dataArray = getPageDataArray(pageModel);
                                for (int j = 0; j < dataArray.size(); j++) {
                                    JsonArray lineArray = dataArray.get(j).getAsJsonArray();
                                    String combineLine = combineTextJsonArray(lineArray);
                                    if (isEmpty(combineLine)) {
                                        continue;
                                    }
                                    if (isProspectus(combineLine)) {
                                        continue;
                                    }
                                    logger.info("抽取{}章发行机构业务模型数据，分析文本：{}。", getChapterModel().getChapterId(), combineLine);
                                    nextExtractItem = fxjgTokenizer.splitWords(extractBizModel, replaceSpaces(combineLine));
                                    if (nextExtractItem == null && currentExtractItem == null) {
                                        logger.error("抽取{}章发行机构业务模型数据，未能分析到发行机构业务模型，分析内容：{}。", getChapterModel().getChapterId(), combineLine);
                                        continue;
                                    } else if (nextExtractItem != null) {
                                        currentExtractItem = nextExtractItem;
                                    }
                                    targetExtractBizModel = getChapterModel().getExtractBizModelMap().get(currentExtractItem.getItemName());
                                    if (!filters.isEmpty()) {
                                        for (String var1 : filters) {
                                            if (combineLine.contains(var1)) {
                                                targetExtractBizModel = null;
                                                currentExtractItem = null;
                                                break;
                                            }
                                        }
                                    }
                                    if (targetExtractBizModel == null) {
                                        logger.error("抽取{}章发行机构业务模型数据，未能分析到或者跳过指定发行机构信息，分析文本：{}。", getChapterModel().getChapterId(), combineLine);
                                        continue;
                                    }
                                    logger.error("抽取{}章发行机构业务模型数据，当前业务模型：{}，分析文本：{}。", getChapterModel().getChapterId(), targetExtractBizModel.getModelName(), combineLine);
                                    combineLine = combineTextJsonArray(dataArray.get(j).getAsJsonArray());
                                    extractItem = fxjgTokenizer.splitWords(targetExtractBizModel, replaceSpaces(combineLine));
                                    if (extractItem != null) {
                                        if (extractItem.getValue() != null) {
                                            continue;
                                        }
                                        combineLine = replaceSpaces(combineLine);
                                        if (isFXJG_SPLIT_Format(combineLine)) {
                                            if (isFilter(combineLine)) {
                                                continue;
                                            }
                                            String splitChar = findFXJG_Format_Split_Char(combineLine);
                                            String[] splits = combineLine.split(splitChar);
                                            if (splits.length == 2) {
                                                try {
                                                    String key = splits[0];
                                                    String value = splits[1];
                                                    KVText kText = new KVText();
                                                    kText.setText(key);
                                                    kText.add(createKVTextLayout(pageModel, lineArray));
                                                    KVText vText = new KVText();
                                                    vText.setText(value);
                                                    vText.add(createKVTextLayout(pageModel, lineArray));
                                                    vText.getTextLayout().setText(vText.getText());
                                                    extractItem.setKey(kText);
                                                    extractItem.setValue(vText);
                                                    kText.setPageNumber(pageModel.getPageNumber());
                                                    vText.setPageNumber(pageModel.getPageNumber());
                                                } catch (Exception e) {
                                                    logger.error(e.getMessage(), e);
                                                }
                                            } else if (splits.length == 3) {
                                                try {
                                                    String key = splits[1];
                                                    String value = splits[2];
                                                    KVText kText = new KVText();
                                                    kText.setText(key);
                                                    kText.add(createKVTextLayout(pageModel, lineArray));
                                                    KVText vText = new KVText();
                                                    vText.setText(value);
                                                    vText.add(createKVTextLayout(pageModel, lineArray));
                                                    vText.getTextLayout().setText(vText.getText());
                                                    extractItem.setKey(kText);
                                                    extractItem.setValue(vText);
                                                    kText.setPageNumber(pageModel.getPageNumber());
                                                    vText.setPageNumber(pageModel.getPageNumber());
                                                } catch (Exception e) {
                                                    logger.error(e.getMessage(), e);
                                                }
                                            } else {
                                                if (getPageModelBottomPageNum(dataArray.get(j + 1).getAsJsonArray())>0) {
                                                    continue;
                                                }
                                                combineLine = combineTextJsonArray(dataArray.get(j + 1).getAsJsonArray());
                                                combineLine = replaceSpaces(combineLine);
                                                if (isFXJG_SPLIT_Format(combineLine)) {
                                                    continue;
                                                }
                                                if (isFilter(combineLine)) {
                                                    continue;
                                                }
                                                try {
                                                    String key = combineLine;
                                                    String value = key;
                                                    KVText kText = new KVText();
                                                    kText.setText(key);
                                                    kText.add(createKVTextLayout(pageModel, lineArray));
                                                    KVText vText = new KVText();
                                                    vText.setText(value);
                                                    vText.add(createKVTextLayout(pageModel, lineArray));
                                                    vText.getTextLayout().setText(vText.getText());
                                                    extractItem.setKey(kText);
                                                    extractItem.setValue(vText);
                                                    kText.setPageNumber(pageModel.getPageNumber());
                                                    vText.setPageNumber(pageModel.getPageNumber());
                                                } catch (Exception e) {
                                                    logger.error(e.getMessage(), e);
                                                }
                                            }
                                        } else {
                                            if (getPageModelBottomPageNum(dataArray.get(j + 1).getAsJsonArray())>0) {
                                                continue;
                                            }
                                            combineLine = combineTextJsonArray(dataArray.get(j + 1).getAsJsonArray());
                                            combineLine = replaceSpaces(combineLine);
                                            if (isFXJG_SPLIT_Format(combineLine)) {
                                                continue;
                                            }
                                            if (isFilter(combineLine)) {
                                                continue;
                                            }
                                            try {
                                                String key = combineLine;
                                                String value = key;
                                                KVText kText = new KVText();
                                                kText.setText(key);
                                                kText.add(createKVTextLayout(pageModel, lineArray));
                                                KVText vText = new KVText();
                                                vText.setText(value);
                                                vText.add(createKVTextLayout(pageModel, lineArray));
                                                vText.getTextLayout().setText(vText.getText());
                                                extractItem.setKey(kText);
                                                extractItem.setValue(vText);
                                                kText.setPageNumber(pageModel.getPageNumber());
                                                vText.setPageNumber(pageModel.getPageNumber());
                                            } catch (Exception e) {
                                                logger.error(e.getMessage(), e);
                                            }
                                        }
                                    }
                                }
                            } else {
                                for (int j = 0; j < extractTableDataList.size(); j++) {
                                    tableData = str2Json(extractTableDataList.get(j));
                                    jsonObject = tableData.getAsJsonArray().get(0).getAsJsonObject();
                                    dataArray = jsonObject.get("data").getAsJsonArray();
                                    for (int k = 0; k < dataArray.size(); k++) {
                                        int offset = 0;
                                        JsonArray itemArray = dataArray.get(k).getAsJsonArray();
                                        JsonObject keyJson = itemArray.get(0).getAsJsonObject();
                                        JsonObject valueJson = itemArray.get(itemArray.size() - 1).getAsJsonObject();
                                        String key = replaceCRLF(keyJson.get("text").getAsString().trim());
                                        if (NumberUtils.isDigits(key)) {
                                            logger.info("抽取{}章发行机构业务模型数据，该列可能为序号，获取下一列，后续改为动态判断。", getChapterModel().getChapterId(), key);
                                            offset = 1;
                                            key = itemArray.get(offset).getAsJsonObject().get("text").getAsString().trim();
                                        }
                                        String value = valueJson.get("text").getAsString();
                                        logger.info("抽取{}章发行机构业务模型数据,分析表格数据内容，第{}条，分析文本：{}。", getChapterModel().getChapterId(), (j + 1), itemArray.toString());
                                        nextExtractItem = fxjgTokenizer.splitWords(extractBizModel, replaceSpaces(key));
                                        if (nextExtractItem != null) {
                                            currentExtractItem = nextExtractItem;
                                            targetExtractBizModel = getChapterModel().getExtractBizModelMap().get(currentExtractItem.getItemName());
                                            if (targetExtractBizModel == null) {
                                                logger.error("抽取{}章发行结构业务模型数据，未能分析到业务模型，分析文本：{}，请确认！！！", getChapterModel().getChapterId(), key);
                                                continue;
                                            }
                                            StringTokenizer stringTokenizer = new StringTokenizer(value, "\r");
                                            List<String> splits = new ArrayList<>();
                                            while (stringTokenizer.hasMoreElements()) {
                                                splits.add((String) stringTokenizer.nextElement());
                                            }
                                            logger.info("抽取{}章发行机构业务模型数据，当前业务模型：{}，分析文本：{}。", getChapterModel().getChapterId(), targetExtractBizModel.getModelName(), splits);
                                            for (int l = 0; l < splits.size(); l++) {
                                                String var1 = splits.get(l);
                                                if (isEmpty(var1)) {
                                                    continue;
                                                }
                                                logger.info("抽取{}章发行机构业务模型数据，当前业务模型：{}，分析文本：{}。", getChapterModel().getChapterId(), targetExtractBizModel.getModelName(), var1);
                                                if (l == 0) {
                                                    if (k == 0) {
                                                        extractItem = targetExtractBizModel.getExtractItem("FXRMC");
                                                    } else {
                                                        extractItem = targetExtractBizModel.getExtractItem("MC");
                                                    }
                                                    if (extractItem == null) {
                                                        continue;
                                                    }
                                                    if (extractItem.getValue() != null) {
                                                        continue;
                                                    }
                                                    try {
                                                        KVText kText = new KVText();
                                                        kText.setText(key);
                                                        KVText vText = new KVText();
                                                        if (isFXJG_SPLIT_Format(var1)) {
                                                            String[] splits2 = var1.split(findFXJG_Format_Split_Char(var1));
                                                            var1 = splits2[splits2.length - 1];
                                                        }
                                                        vText.setText(var1);
                                                        kText.add(createKVTextLayout(pageModel, keyJson));
                                                        vText.add(createKVTextLayout(pageModel, keyJson));
                                                        vText.getTextLayout().setText(vText.getText());
                                                        extractItem.setKey(kText);
                                                        extractItem.setValue(vText);
                                                        kText.setPageNumber(pageModel.getPageNumber());
                                                        vText.setPageNumber(pageModel.getPageNumber());
                                                    } catch (Exception e) {
                                                        logger.error(e.getMessage(), e);
                                                    }
                                                } else if (l >= 1) {
                                                    extractItem = fxjgTokenizer.splitWords(targetExtractBizModel, replaceSpaces(var1));
                                                    if (extractItem == null) {
                                                        logger.error("抽取{}章发行结构业务模型数据，未能分析到业务模型，分析文本：{}，请确认！！！", getChapterModel().getChapterId(), var1);
                                                        continue;
                                                    }
                                                    if (l < splits.size() - 2) {
                                                        String var2 = splits.get(l + 1);
                                                        if (fxjgTokenizer.splitWords(targetExtractBizModel, replaceSpaces(var2)) == null) {
                                                            var1 += var2;
                                                            l += 1;
                                                            continue;
                                                        }
                                                    }
                                                    if (extractItem.getValue() != null) {
                                                        continue;
                                                    }
                                                    KVText kText = null;
                                                    try {
                                                        kText = new KVText();
                                                        kText.setText(key);
                                                        KVText vText = new KVText();
                                                        vText.setText(var1);
                                                        kText.add(createKVTextLayout(pageModel, keyJson));
                                                        vText.add(createKVTextLayout(pageModel, keyJson));
                                                        vText.getTextLayout().setText(vText.getText());
                                                        extractItem.setKey(kText);
                                                        extractItem.setValue(vText);
                                                        kText.setPageNumber(pageModel.getPageNumber());
                                                        vText.setPageNumber(pageModel.getPageNumber());
                                                    } catch (Exception e) {
                                                        logger.error(e.getMessage(), e);
                                                    }
                                                }
                                            }
                                            logger.info("抽取{}章发行结构业务模型数据，分析到发行机构业务指标，指标名称：{}，指标内容：{}。", getChapterModel().getChapterId(), currentExtractItem.getItemName(), key);
                                            continue;
                                        } else {

                                        }
                                    }
                                }
                            }
                        }
                        break;
                    case TABLE:
                        break;
                    case DEFAULT:
                        break;
                }
            } else {
                logger.error("抽取{}章发行机构业务模型数据，PDF文档：{}，当前页码：{}不存在，请检查！", getChapterModel().getChapterId(), getDocumentModel().getPdfFilePath(), pageModel.getPageNumber());
            }
        }
        fxjgTokenizer.unloadCoreSynonyms2(extractBizModelMap);
        fxjgTokenizer.unloadCoreSynonyms(extractBizModel);
        long t2 = System.currentTimeMillis();
        logger.info("抽取{}章发行机构业务模型数据模型完成，耗时：{}毫秒。", getChapterModel().getChapterId(), (t2 - t1));
    }

    private boolean isFilter(String text) {
        String regex = "((\\([一二三四五六七八九十]{1,2}\\))|(\\d{1})){1}\\、?\\s?[\\u0391-\\uFFE5]+\\s{0,}$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);
        return matcher.matches();
    }
}
